/************************************************************************/
/* FXEvent.cpp                                                          */
/* 2004/04/15                                                           */
/************************************************************************/

#include <d3dx9.h>
#include <typeinfo>
#include "dxutil.h"
#include "FXDataStruct.h"
#include "FXEvent.h"


using namespace FX;

/************************************************************************/
/*                                                                      */
/************************************************************************/
                    
void
CFXColorEvent::Apply( CFXElement& element )
{   
    if (_pNext)
    {   
        float fTimeDelta = _pNext->GetKey() - GetKey();
        if (fTimeDelta <= 0) { fTimeDelta = 1.0f; }

        const D3DXCOLOR& colorNext = 
            static_cast<CFXColorEvent*>(_pNext)->GetValue();
        element.SetColorStep((colorNext - GetValue()) / fTimeDelta);
    }
    return;
}


/************************************************************************/
/*                                                                      */
/************************************************************************/
void
CFXVelocityEvent::Apply( CFXElement& element )
{
    return;
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
void 
CFXPosEvent::Apply( CFXElement& element )
{
    if (_pNext)
    {   
        float fTimeDelta = _pNext->GetKey() - GetKey();
        if (fTimeDelta <= 0) { fTimeDelta = 1.0f; }

        const D3DXVECTOR3& vDirNext = 
            static_cast<CFXPosEvent*>(_pNext)->GetValue();
        element.SetDir((vDirNext - GetValue()) / fTimeDelta);
    }
    return;
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
void
CFXScaleEvent::Apply( CFXElement& element )
{
    if (_pNext)
    {   
        float fTimeDelta = _pNext->GetKey() - GetKey();
        if (fTimeDelta <= 0) { fTimeDelta = 1.0f; }

        const D3DXVECTOR3& vScaleNext = 
            static_cast<CFXScaleEvent*>(_pNext)->GetValue();
        element.SetScaleStep((vScaleNext - GetValue()) / fTimeDelta);
    }
    return;
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
/************************************************************************/
/*                                                                      */
/************************************************************************/
void 
CFXRotZEvent::Apply( CFXElement& element )
{
    if (_pNext)
    {   
        float fTimeDelta = _pNext->GetKey() - GetKey();
        if (fTimeDelta <= 0) { fTimeDelta = 1.0f; }

        float fRotZNext = 
            static_cast<CFXRotZEvent*>(_pNext)->GetValue();
        element.SetRotZAngleStep((fRotZNext - GetValue()) / fTimeDelta);
    }
    return;
} 

/************************************************************************/
/*                                                                      */
/************************************************************************/

void 
CFXRotEvent::Apply( CFXElement& element )
{
  /*
    if (_pNext)
      {
          float fTimeDelta = (element.GetAge() - GetKey()) /
                              (_pNext->GetKey() - GetKey());
          D3DXQUATERNION qRotNext = 
              dynamic_cast<CFXRotEvent*>(_pNext)->GetValue();
          D3DXQUATERNION qRotNew;
          D3DXQuaternionSlerp(&qRotNew, &GetValue(), &qRotNext, fTimeDelta);
          
          element.SetRotZAngle(element.GetRotZAngle() * qRotNew);
      }
    */
  
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
void 
CFXTextureChangeEvent::Apply( CFXElement& element )
{
    element.SetTexture(GetValue());
    
}

/**********************   CFXEventOptimizer    **************************/

/************************************************************************/
/*                                                                      */
/************************************************************************/
void CFXEventListOptimizer::SortEvents(
                        std::vector<IFXEvent*>& eventVector
                                      )
{
    CEventCompareFunc compFunc;
    std::sort(eventVector.begin(), eventVector.end(), compFunc);
}

/************************************************************************/
/*                                                                      */
/************************************************************************/
void CFXEventListOptimizer::CreateFadeList(
                              std::vector<IFXEvent*>& eventVector
                                          )
{
    std::vector<IFXEvent*>::iterator eventIter1 = eventVector.begin();
    while ( eventIter1 != eventVector.end())
    {
        std::vector<IFXEvent*>::iterator eventIter2 = eventIter1;
        while (eventIter2 != eventVector.end())
        {
            if ( 
                (eventIter2 != eventIter1 )&& 
                (typeid(**eventIter2) ==  typeid(**eventIter1))
                )
            {
                (*eventIter1)->SetNext(*eventIter2);
                break;
            }
            ++eventIter2;
        } 
        ++eventIter1;
    }
}
